home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
frasrc19.zip
/
LSYS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-25
|
26KB
|
966 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef __TURBOC__
#include <alloc.h>
#else
#include <malloc.h>
#endif
#include "fractint.h"
#include "prototyp.h"
#include "lsys.h"
struct lsys_cmd {
void (*f)(struct lsys_turtlestatei *);
long n;
char ch;
};
static int _fastcall readLSystemFile(char *);
static void _fastcall free_rules_mem(void);
static int _fastcall save_rule(char *,char far **);
static void free_lcmds(void);
static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *,struct lsys_turtlestatei *, struct lsys_cmd far **,int);
static struct lsys_cmd far * drawLSysI(struct lsys_cmd far *command,struct lsys_turtlestatei *ts, struct lsys_cmd far **rules,int depth);
static int lsysi_findscale(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth);
static struct lsys_cmd far *LSysISizeTransform(char far *s, struct lsys_turtlestatei *ts);
static struct lsys_cmd far *LSysIDrawTransform(char far *s, struct lsys_turtlestatei *ts);
static void _fastcall lsysi_dosincos(void);
static void lsysi_doslash(struct lsys_turtlestatei *cmd);
static void lsysi_dobslash(struct lsys_turtlestatei *cmd);
static void lsysi_doat(struct lsys_turtlestatei *cmd);
static void lsysi_dopipe(struct lsys_turtlestatei *cmd);
static void lsysi_dosizedm(struct lsys_turtlestatei *cmd);
static void lsysi_dosizegf(struct lsys_turtlestatei *cmd);
static void lsysi_dodrawd(struct lsys_turtlestatei *cmd);
static void lsysi_dodrawm(struct lsys_turtlestatei *cmd);
static void lsysi_dodrawg(struct lsys_turtlestatei *cmd);
static void lsysi_dodrawf(struct lsys_turtlestatei *cmd);
static void lsysi_dodrawc(struct lsys_turtlestatei *cmd);
static void lsysi_dodrawgt(struct lsys_turtlestatei *cmd);
static void lsysi_dodrawlt(struct lsys_turtlestatei *cmd);
/* Some notes to Adrian from PB, made when I integrated with v15:
printfs changed to work with new user interface
bug at end of readLSystemFile, the line which said rulind=0 fixed
to say *rulind=0
the calloc was not worthwhile, it was just for a 54 byte area, cheaper
to keep it as a static; but there was a static 201 char buffer I
changed to not be static
use of strdup was a nono, caused problems running out of space cause
the memory allocated each time was never freed; I've changed to
use far memory and to free when done
*/
#define sins ((long *)(boxy))
#define coss (((long *)(boxy)+50)) /* 50 after the start of sins */
static char far *ruleptrs[MAXRULES];
static struct lsys_cmd far *rules2[MAXRULES];
char maxangle;
static char loaded=0;
int _fastcall ispow2(int n)
{
return (n == (n & -n));
}
LDBL _fastcall getnumber(char far **str)
{
char numstr[30];
LDBL ret;
int i,root,inverse;
root=0;
inverse=0;
strcpy(numstr,"");
(*str)++;
switch (**str)
{
case 'q':
root=1;
(*str)++;
break;
case 'i':
inverse=1;
(*str)++;
break;
}
switch (**str)
{
case 'q':
root=1;
(*str)++;
break;
case 'i':
inverse=1;
(*str)++;
break;
}
i=0;
while ((**str<='9' && **str>='0') || **str=='.')
{
numstr[i++]= **str;
(*str)++;
}
(*str)--;
numstr[i]=0;
ret=atof(numstr);
if (ret <= 0.0) /* this is a sanity check, JCO 8/31/94 */
return 0;
if (root)
ret=sqrtl(ret);
if (inverse)
ret = 1.0/ret;
return ret;
}
static int _fastcall readLSystemFile(char *str)
{
int c;
char far **rulind;
int err=0;
int linenum,check=0;
char inline[161],fixed[161],*word;
FILE *infile;
char msgbuf[481]; /* enough for 6 full lines */
if (find_file_item(LFileName,str,&infile) < 0)
return -1;
while ((c = fgetc(infile)) != '{')
if (c == EOF) return -1;
maxangle=0;
for(linenum=0;linenum<MAXRULES;++linenum) ruleptrs[linenum]=NULL;
rulind= &ruleptrs[1];
msgbuf[0]=(char)(linenum=0);
while(file_gets(inline,160,infile)) /* Max line length 160 chars */
{
linenum++;
if ((word = strchr(inline,';')) != NULL) /* strip comment */
*word = 0;
strlwr(inline);
if (strspn(inline," \t\n") < strlen(inline)) /* not a blank line */
{
word=strtok(inline," =\t\n");
if (!strcmp(word,"axiom"))
{
if (save_rule(strtok(NULL," \t\n"),&ruleptrs[0])) {
strcat(msgbuf,"Error: out of memory\n");
++err;
break;
}
check=1;
}
else if (!strcmp(word,"angle"))
{
maxangle=(char)atoi(strtok(NULL," \t\n"));
check=1;
}
else if (!strcmp(word,"}"))
break;
else if (strcspn(word,"+-/\\@|!c<>][") == 0 && strlen(word) == 1)
{
sprintf(&msgbuf[strlen(msgbuf)],
"Syntax error line %d: Redefined reserved symbol %s\n",linenum,word);
++err;
break;
}
else if (strlen(word)==1)
{
strcat(strcpy(fixed,word),strtok(NULL," \t\n"));
if (save_rule(fixed,rulind++)) {
strcat(msgbuf, "Error: out of memory\n");
++err;
break;
}
check=1;
}
else
if (err<6)
{
sprintf(&msgbuf[strlen(msgbuf)],
"Syntax error line %d: %s\n",linenum,word);
++err;
}
if (check)
{
check=0;
if((word=strtok(NULL," \t\n"))!=NULL)
if (err<6)
{
sprintf(&msgbuf[strlen(msgbuf)],
"Extra text after command line %d: %s\n",linenum,word);
++err;
}
}
}
}
fclose(infile);
if (!ruleptrs[0] && err<6)
{
strcat(msgbuf,"Error: no axiom\n");
++err;
}
if ((maxangle<3||maxangle>50) && err<6)
{
strcat(msgbuf,"Error: illegal or missing angle\n");
++err;
}
if (err)
{
msgbuf[strlen(msgbuf)-1]=0; /* strip trailing \n */
stopmsg(0,msgbuf);
return -1;
}
*rulind=NULL;
return 0;
}
int Lsystem(void)
{
int order;
char far **rulesc;
struct lsys_cmd far **sc;
int stackoflow = 0;
if ( (!loaded) && LLoad())
return -1;
overflow = 0; /* reset integer math overflow flag */
order=(int)param[0];
if (order<=0)
order=0;
if (usr_floatflag)
overflow = 1;
else {
struct lsys_turtlestatei ts;
ts.stackoflow = 0;
ts.maxangle = maxangle;
ts.dmaxangle = (char)(maxangle - 1);
sc = rules2;
for (rulesc = ruleptrs; *rulesc; rulesc++)
*sc++ = LSysISizeTransform(*rulesc, &ts);
*sc = NULL;
lsysi_dosincos();
if (lsysi_findscale(rules2[0], &ts, &rules2[1], order)) {
ts.realangle = ts.angle = ts.reverse = 0;
free_lcmds();
sc = rules2;
for (rulesc = ruleptrs; *rulesc; rulesc++)
*sc++ = LSysIDrawTransform(*rulesc, &ts);
*sc = NULL;
/* !! HOW ABOUT A BETTER WAY OF PICKING THE DEFAULT DRAWING COLOR */
if ((ts.curcolor=15) > colors)
ts.curcolor=(char)(colors-1);
drawLSysI(rules2[0], &ts, &rules2[1], order);
}
stackoflow = ts.stackoflow;
}
if (stackoflow) {
static char far msg[]={"insufficient memory, try a lower order"};
stopmsg(0,msg);
}
else if (overflow) {
struct lsys_turtlestatef ts;
overflow = 0;
ts.stackoflow = 0;
ts.maxangle = maxangle;
ts.dmaxangle = (char)(maxangle - 1);
sc = rules2;
for (rulesc = ruleptrs; *rulesc; rulesc++)
*sc++ = LSysFSizeTransform(*rulesc, &ts);
*sc = NULL;
lsysf_dosincos();
if (lsysf_findscale(rules2[0], &ts, &rules2[1], order)) {
ts.realangle = ts.angle = ts.reverse = 0;
free_lcmds();
sc = rules2;
for (rulesc = ruleptrs; *rulesc; rulesc++)
*sc++ = LSysFDrawTransform(*rulesc, &ts);
*sc = NULL;
/* !! HOW ABOUT A BETTER WAY OF PICKING THE DEFAULT DRAWING COLOR */
if ((ts.curcolor=15) > colors)
ts.curcolor=(char)(colors-1);
lsys_prepfpu(&ts);
drawLSysF(rules2[0], &ts, &rules2[1], order);
lsys_donefpu(&ts);
}
overflow = 0;
}
free_rules_mem();
free_lcmds();
loaded=0;
return 0;
}
int LLoad(void)
{
if (readLSystemFile(LName)) { /* error occurred */
free_rules_mem();
loaded=0;
return -1;
}
loaded=1;
return 0;
}
static void _fastcall free_rules_mem(void)
{
int i;
for(i=0;i<MAXRULES;++i)
if(ruleptrs[i]) farmemfree(ruleptrs[i]);
}
static int _fastcall save_rule(char *rule,char far **saveptr)
{
int i;
char far *tmpfar;
i=strlen(rule)+1;
if((tmpfar=farmemalloc((long)i))==NULL) {
return -1;
}
*saveptr=tmpfar;
while(--i>=0) *(tmpfar++)= *(rule++);
return 0;
}
static void free_lcmds(void)
{
struct lsys_cmd far **sc = rules2;
while (*sc)
farmemfree(*sc++);
}
#ifdef XFRACT
#define lsysi_doslash_386 lsysi_doslash
#define lsysi_dobslash_386 lsysi_dobslash
#define lsys_doat lsysi_doat
#define lsys_dosizegf lsysi_dosizegf
#define lsys_dodrawg lsysi_dodrawg
void lsys_prepfpu(struct lsys_turtlestatef *x) { }
void lsys_donefpu(struct lsys_turtlestatef *x) { }
#endif
/* integer specific routines */
#ifdef XFRACT
static void lsysi_doplus(struct lsys_turtlestatei *cmd)
{
if (cmd->reverse) {
if (++cmd->angle == cmd->maxangle)
cmd->angle = 0;
}
else {
if (cmd->angle)
cmd->angle--;
else
cmd->angle = cmd->dmaxangle;
}
}
#else
extern void lsysi_doplus(struct lsys_turtlestatei *cmd);
#endif
#ifdef XFRACT
/* This is the same as lsys_doplus, except maxangle is a power of 2. */
static void lsysi_doplus_pow2(struct lsys_turtlestatei *cmd)
{
if (cmd->reverse) {
cmd->angle++;
cmd->angle &= cmd->dmaxangle;
}
else {
cmd->angle--;
cmd->angle &= cmd->dmaxangle;
}
}
#else
extern void lsysi_doplus_pow2(struct lsys_turtlestatei *cmd);
#endif
#ifdef XFRACT
static void lsysi_dominus(struct lsys_turtlestatei *cmd)
{
if (cmd->reverse) {
if (cmd->angle)
cmd->angle--;
else
cmd->angle = cmd->dmaxangle;
}
else {
if (++cmd->angle == cmd->maxangle)
cmd->angle = 0;
}
}
#else
extern void lsysi_dominus(struct lsys_turtlestatei *cmd);
#endif
#ifdef XFRACT
static void lsysi_dominus_pow2(struct lsys_turtlestatei *cmd)
{
if (cmd->reverse) {
cmd->angle--;
cmd->angle &= cmd->dmaxangle;
}
else {
cmd->angle++;
cmd->angle &= cmd->dmaxangle;
}
}
#else
extern void lsysi_dominus_pow2(struct lsys_turtlestatei *cmd);
#endif
static void lsysi_doslash(struct lsys_turtlestatei *cmd)
{
if (cmd->reverse)
cmd->realangle -= cmd->num;
else
cmd->realangle += cmd->num;
}
#ifndef XFRACT
extern void lsysi_doslash_386(struct lsys_turtlestatei *cmd);
#endif
static void lsysi_dobslash(struct lsys_turtlestatei *cmd)
{
if (cmd->reverse)
cmd->realangle += cmd->num;
else
cmd->realangle -= cmd->num;
}
#ifndef XFRACT
extern void lsysi_dobslash_386(struct lsys_turtlestatei *cmd);
#endif
static void lsysi_doat(struct lsys_turtlestatei *cmd)
{
cmd->size = multiply(cmd->size, cmd->num, 19);
}
static void lsysi_dopipe(struct lsys_turtlestatei *cmd)
{
cmd->angle = (char)(cmd->angle + (char)(cmd->maxangle / 2));
cmd->angle %= cmd->maxangle;
}
#ifdef XFRACT
static void lsysi_dopipe_pow2(struct lsys_turtlestatei *cmd)
{
cmd->angle += cmd->maxangle >> 1;
cmd->angle &= cmd->dmaxangle;
}
#else
extern void lsysi_dopipe_pow2(struct lsys_turtlestatei *cmd);
#endif
#ifdef XFRACT
static void lsysi_dobang(struct lsys_turtlestatei *cmd)
{
cmd->reverse = ! cmd->reverse;
}
#else
extern void lsysi_dobang(struct lsys_turtlestatei *cmd);
#endif
static void lsysi_dosizedm(struct lsys_turtlestatei *cmd)
{
double angle = (double) cmd->realangle * ANGLE2DOUBLE;
double s, c;
long fixedsin, fixedcos;
FPUsincos(&angle, &s, &c);
fixedsin = (long) (s * FIXEDLT1);
fixedcos = (long) (c * FIXEDLT1);
cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29));
cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29));
/* xpos+=size*aspect*cos(realangle*PI/180); */
/* ypos+=size*sin(realangle*PI/180); */
if (cmd->xpos>cmd->xmax) cmd->xmax=cmd->xpos;
if (cmd->ypos>cmd->ymax) cmd->ymax=cmd->ypos;
if (cmd->xpos<cmd->xmin) cmd->xmin=cmd->xpos;
if (cmd->ypos<cmd->ymin) cmd->ymin=cmd->ypos;
}
static void lsysi_dosizegf(struct lsys_turtlestatei *cmd)
{
cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[cmd->angle], 29));
cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[cmd->angle], 29));
/* xpos+=size*coss[angle]; */
/* ypos+=size*sins[angle]; */
if (cmd->xpos>cmd->xmax) cmd->xmax=cmd->xpos;
if (cmd->ypos>cmd->ymax) cmd->ymax=cmd->ypos;
if (cmd->xpos<cmd->xmin) cmd->xmin=cmd->xpos;
if (cmd->ypos<cmd->ymin) cmd->ymin=cmd->ypos;
}
static void lsysi_dodrawd(struct lsys_turtlestatei *cmd)
{
double angle = (double) cmd->realangle * ANGLE2DOUBLE;
double s, c;
long fixedsin, fixedcos;
int lastx, lasty;
FPUsincos(&angle, &s, &c);
fixedsin = (long) (s * FIXEDLT1);
fixedcos = (long) (c * FIXEDLT1);
lastx=(int) (cmd->xpos >> 19);
lasty=(int) (cmd->ypos >> 19);
cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29));
cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29));
/* xpos+=size*aspect*cos(realangle*PI/180); */
/* ypos+=size*sin(realangle*PI/180); */
draw_line(lastx,lasty,(int)(cmd->xpos >> 19),(int)(cmd->ypos >> 19),cmd->curcolor);
}
static void lsysi_dodrawm(struct lsys_turtlestatei *cmd)
{
double angle = (double) cmd->realangle * ANGLE2DOUBLE;
double s, c;
long fixedsin, fixedcos;
FPUsincos(&angle, &s, &c);
fixedsin = (long) (s * FIXEDLT1);
fixedcos = (long) (c * FIXEDLT1);
/* xpos+=size*aspect*cos(realangle*PI/180); */
/* ypos+=size*sin(realangle*PI/180); */
cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29));
cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29));
}
static void lsysi_dodrawg(struct lsys_turtlestatei *cmd)
{
cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[cmd->angle], 29));
cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[cmd->angle], 29));
/* xpos+=size*coss[angle]; */
/* ypos+=size*sins[angle]; */
}
static void lsysi_dodrawf(struct lsys_turtlestatei *cmd)
{
int lastx = (int) (cmd->xpos >> 19);
int lasty = (int) (cmd->ypos >> 19);
cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[cmd->angle], 29));
cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[cmd->angle], 29));
/* xpos+=size*coss[angle]; */
/* ypos+=size*sins[angle]; */
draw_line(lastx,lasty,(int)(cmd->xpos >> 19),(int)(cmd->ypos >> 19),cmd->curcolor);
}
static void lsysi_dodrawc(struct lsys_turtlestatei *cmd)
{
cmd->curcolor = (char)(((int) cmd->num) % colors);
}
static void lsysi_dodrawgt(struct lsys_turtlestatei *cmd)
{
cmd->curcolor = (char)(cmd->curcolor - (char)cmd->num);
if ((cmd->curcolor %= colors) == 0)
cmd->curcolor = (char)(colors-1);
}
static void lsysi_dodrawlt(struct lsys_turtlestatei *cmd)
{
cmd->curcolor = (char)(cmd->curcolor + (char)cmd->num);
if ((cmd->curcolor %= colors) == 0)
cmd->curcolor = 1;
}
static struct lsys_cmd far * _fastcall
findsize(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth)
{
struct lsys_cmd far **rulind;
int tran;
if (overflow) /* integer math routines overflowed */
return NULL;
#ifndef __TURBOC__
if (stackavail() < 400) { /* leave some margin for calling subrtns */
ts->stackoflow = 1;
return NULL;
}
#endif
while (command->ch && command->ch !=']') {
if (! (ts->counter++)) {
/* let user know we're not dead */
if (thinking(1,"L-System thinking (higher orders take longer)")) {
ts->counter--;
return NULL;
}
}
tran=0;
if (depth) {
for(rulind=rules;*rulind;rulind++)
if ((*rulind)->ch==command->ch) {
tran=1;
if (findsize((*rulind)+1,ts,rules,depth-1) == NULL)
return(NULL);
}
}
if (!depth || !tran) {
if (command->f) {
ts->num = command->n;
(*command->f)(ts);
}
else if (command->ch == '[') {
char saveang,saverev;
long savesize,savex,savey;
unsigned long saverang;
saveang=ts->angle;
saverev=ts->reverse;
savesize=ts->size;
saverang=ts->realangle;
savex=ts->xpos;
savey=ts->ypos;
if ((command=findsize(command+1,ts,rules,depth)) == NULL)
return(NULL);
ts->angle=saveang;
ts->reverse=saverev;
ts->size=savesize;
ts->realangle=saverang;
ts->xpos=savex;
ts->ypos=savey;
}
}
command++;
}
return command;
}
static int
lsysi_findscale(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth)
{
float horiz,vert;
double xmin, xmax, ymin, ymax;
double locsize;
double locaspect;
struct lsys_cmd far *fsret;
locaspect=screenaspect*xdots/ydots;
ts->aspect = FIXEDPT(locaspect);
ts->xpos =
ts->ypos =
ts->xmin =
ts->xmax =
ts->ymax =
ts->ymin =
ts->realangle =
ts->angle =
ts->reverse =
ts->counter = 0;
ts->size=FIXEDPT(1L);
fsret = findsize(command,ts,rules,depth);
thinking(0, NULL); /* erase thinking message if any */
xmin = (double) ts->xmin / FIXEDMUL;
xmax = (double) ts->xmax / FIXEDMUL;
ymin = (double) ts->ymin / FIXEDMUL;
ymax = (double) ts->ymax / FIXEDMUL;
if (fsret == NULL)
return 0;
if (xmax == xmin)
horiz = (float)1E37;
else
horiz = (float)((xdots-10)/(xmax-xmin));
if (ymax == ymin)
vert = (float)1E37;
else
vert = (float)((ydots-6) /(ymax-ymin));
locsize = (vert<horiz) ? vert : horiz;
if (horiz == 1E37)
ts->xpos = FIXEDPT(xdots/2);
else
/* ts->xpos = FIXEDPT(-xmin*(locsize)+5+((xdots-10)-(locsize)*(xmax-xmin))/2); */
ts->xpos = FIXEDPT((xdots-locsize*(xmax+xmin))/2);
if (vert == 1E37)
ts->ypos = FIXEDPT(ydots/2);
else
/* ts->ypos = FIXEDPT(-ymin*(locsize)+3+((ydots-6)-(locsize)*(ymax-ymin))/2); */
ts->ypos = FIXEDPT((ydots-locsize*(ymax+ymin))/2);
ts->size = FIXEDPT(locsize);
return 1;
}
static struct lsys_cmd far *
drawLSysI(struct lsys_cmd far *command,struct lsys_turtlestatei *ts, struct lsys_cmd far **rules,int depth)
{
struct lsys_cmd far **rulind;
int tran;
if (overflow) /* integer math routines overflowed */
return NULL;
#ifndef __TURBOC__
if (stackavail() < 400) { /* leave some margin for calling subrtns */
ts->stackoflow = 1;
return NULL;
}
#endif
while (command->ch && command->ch !=']') {
if (!(ts->counter++)) {
if (keypressed()) {
ts->counter--;
return NULL;
}
}
tran=0;
if (depth) {
for(rulind=rules;*rulind;rulind++)
if ((*rulind)->ch == command->ch) {
tran=1;
if (drawLSysI((*rulind)+1,ts,rules,depth-1) == NULL)
return NULL;
}
}
if (!depth||!tran) {
if (command->f) {
ts->num = command->n;
(*command->f)(ts);
}
else if (command->ch == '[') {
char saveang,saverev,savecolor;
long savesize,savex,savey;
unsigned long saverang;
saveang=ts->angle;
saverev=ts->reverse;
savesize=ts->size;
saverang=ts->realangle;
savex=ts->xpos;
savey=ts->ypos;
savecolor=ts->curcolor;
if ((command=drawLSysI(command+1,ts,rules,depth)) == NULL)
return(NULL);
ts->angle=saveang;
ts->reverse=saverev;
ts->size=savesize;
ts->realangle=saverang;
ts->xpos=savex;
ts->ypos=savey;
ts->curcolor=savecolor;
}
}
command++;
}
return command;
}
static struct lsys_cmd far *
LSysISizeTransform(char far *s, struct lsys_turtlestatei *ts)
{
struct lsys_cmd far *ret;
struct lsys_cmd far *doub;
int maxval = 10;
int n = 0;
void (*f)();
long num;
void (*plus)() = (ispow2(ts->maxangle)) ? lsysi_doplus_pow2 : lsysi_doplus;
void (*minus)() = (ispow2(ts->maxangle)) ? lsysi_dominus_pow2 : lsysi_dominus;
void (*pipe)() = (ispow2(ts->maxangle)) ? lsysi_dopipe_pow2 : lsysi_dopipe;
void (*slash)() = (cpu >= 386) ? lsysi_doslash_386 : lsysi_doslash;
void (*bslash)() = (cpu >= 386) ? lsysi_dobslash_386 : lsysi_dobslash;
void (*at)() = (cpu >= 386) ? lsysi_doat_386 : lsysi_doat;
void (*dogf)() = (cpu >= 386) ? lsysi_dosizegf_386 : lsysi_dosizegf;
ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd));
if (ret == NULL) {
ts->stackoflow = 1;
return NULL;
}
while (*s) {
f = NULL;
num = 0;
ret[n].ch = *s;
switch (*s) {
case '+': f = plus; break;
case '-': f = minus; break;
case '/': f = slash; num = (long) (getnumber(&s) * 11930465L); break;
case '\\': f = bslash; num = (long) (getnumber(&s) * 11930465L); break;
case '@': f = at; num = FIXEDPT(getnumber(&s)); break;
case '|': f = pipe; break;
case '!': f = lsysi_dobang; break;
case 'd':
case 'm': f = lsysi_dosizedm; break;
case 'g':
case 'f': f = dogf; break;
case '[': num = 1; break;
case ']': num = 2; break;
default:
num = 3;
break;
}
#ifdef XFRACT
ret[n].f = (void (*)())f;
#else
ret[n].f = (void (*)(struct lsys_turtlestatei *))f;
#endif
ret[n].n = num;
if (++n == maxval) {
doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd));
if (doub == NULL) {
farmemfree(ret);
ts->stackoflow = 1;
return NULL;
}
far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd));
farmemfree(ret);
ret = doub;
maxval <<= 1;
}
s++;
}
ret[n].ch = 0;
ret[n].f = NULL;
ret[n].n = 0;
n++;
doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd));
if (doub == NULL) {
farmemfree(ret);
ts->stackoflow = 1;
return NULL;
}
far_memcpy(doub, ret, n*sizeof(struct lsys_cmd));
farmemfree(ret);
return doub;
}
static struct lsys_cmd far *
LSysIDrawTransform(char far *s, struct lsys_turtlestatei *ts)
{
struct lsys_cmd far *ret;
struct lsys_cmd far *doub;
int maxval = 10;
int n = 0;
void (*f)();
long num;
void (*plus)() = (ispow2(ts->maxangle)) ? lsysi_doplus_pow2 : lsysi_doplus;
void (*minus)() = (ispow2(ts->maxangle)) ? lsysi_dominus_pow2 : lsysi_dominus;
void (*pipe)() = (ispow2(ts->maxangle)) ? lsysi_dopipe_pow2 : lsysi_dopipe;
void (*slash)() = (cpu >= 386) ? lsysi_doslash_386 : lsysi_doslash;
void (*bslash)() = (cpu >= 386) ? lsysi_dobslash_386 : lsysi_dobslash;
void (*at)() = (cpu >= 386) ? lsysi_doat_386 : lsysi_doat;
void (*drawg)() = (cpu >= 386) ? lsysi_dodrawg_386 : lsysi_dodrawg;
ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd));
if (ret == NULL) {
ts->stackoflow = 1;
return NULL;
}
while (*s) {
f = NULL;
num = 0;
ret[n].ch = *s;
switch (*s) {
case '+': f = plus; break;
case '-': f = minus; break;
case '/': f = slash; num = (long) (getnumber(&s) * 11930465L); break;
case '\\': f = bslash; num = (long) (getnumber(&s) * 11930465L); break;
case '@': f = at; num = FIXEDPT(getnumber(&s)); break;
case '|': f = pipe; break;
case '!': f = lsysi_dobang; break;
case 'd': f = lsysi_dodrawd; break;
case 'm': f = lsysi_dodrawm; break;
case 'g': f = drawg; break;
case 'f': f = lsysi_dodrawf; break;
case 'c': f = lsysi_dodrawc; num = (long) getnumber(&s); break;
case '<': f = lsysi_dodrawlt; num = (long) getnumber(&s); break;
case '>': f = lsysi_dodrawgt; num = (long) getnumber(&s); break;
case '[': num = 1; break;
case ']': num = 2; break;
default:
num = 3;
break;
}
#ifdef XFRACT
ret[n].f = (void (*)())f;
#else
ret[n].f = (void (*)(struct lsys_turtlestatei *))f;
#endif
ret[n].n = num;
if (++n == maxval) {
doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd));
if (doub == NULL) {
farmemfree(ret);
ts->stackoflow = 1;
return NULL;
}
far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd));
farmemfree(ret);
ret = doub;
maxval <<= 1;
}
s++;
}
ret[n].ch = 0;
ret[n].f = NULL;
ret[n].n = 0;
n++;
doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd));
if (doub == NULL) {
farmemfree(ret);
ts->stackoflow = 1;
return NULL;
}
far_memcpy(doub, ret, n*sizeof(struct lsys_cmd));
farmemfree(ret);
return doub;
}
static void _fastcall lsysi_dosincos(void)
{
double locaspect;
double TWOPI = 2.0 * PI;
double twopimax;
double twopimaxi;
double s, c;
int i;
locaspect=screenaspect*xdots/ydots;
twopimax = TWOPI / maxangle;
for(i=0;i<maxangle;i++) {
twopimaxi = i * twopimax;
FPUsincos(&twopimaxi, &s, &c);
sins[i] = (long) (s * FIXEDLT1);
coss[i] = (long) ((locaspect * c) * FIXEDLT1);
}
}